home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / DEMON / RISCOS2 / TCP_131S.ARC / c / NetTime < prev    next >
Text File  |  1994-03-03  |  7KB  |  267 lines

  1. /*************************************************************************** 
  2.      Purpose        :    Routines for setting KA9Q's time from the remote host.     
  3.                  :    Uses the protocol described in RFC 868.                     
  4.  *************************************************************************** 
  5.                  :    Copyright Giles Todd 1992.  All rights reserved.         
  6.                  :    The right of Giles Todd to be identified as the author     
  7.                  :    of this work has been asserted by him in accordance         
  8.                  :    with the Copyrights, Designs and Patents Act, 1988.         
  9.                  :    No restrictions on the use of this module with KA9Q.     
  10.  ***************************************************************************/
  11.  
  12. #include    <stdio.h>
  13. #include    <stdlib.h>
  14. #include    <time.h>
  15. #include    "Arc.h"
  16. #include    "domain.h"
  17. #include    "global.h"
  18. #include    "mbuf.h"
  19. #include    "misc.h"
  20. #include    "cmdparse.h"
  21. #include    "socket.h"
  22. #include    "timer.h"
  23. #include    "netuser.h"
  24. #include    "udp.h"
  25.  
  26. int done_set_time = 0;    /* have we set the time since this open?    */
  27.  
  28. #define TIME_PORT 37
  29.  
  30. extern int16 lport;                     /* local port placeholder */
  31. extern int32 wimp_ver;
  32.  
  33. /*************************************************************************** 
  34.      Static function declarations.                                             
  35.  ***************************************************************************/
  36.  
  37. static int do_server (int argc, char **argv);
  38. static int do_maxcorrect (int argc, char **argv);
  39. static int do_mincorrect (int argc, char **argv);
  40. static int do_read (int argc, char **argv);
  41. static int do_set (int argc, char **argv);
  42.  
  43. /*************************************************************************** 
  44.      Static data.                                                             
  45.  ***************************************************************************/
  46.  
  47. static time_t correction     = 0;            /* difference in seconds         */
  48.                                             /* between remote and PC clock    */
  49. static int32 server          = 0L;            /* time server address            */
  50. static time_t max_correction = 0;            /* !0 is max correction allowed */
  51. static time_t min_correction = 0;            /* !0 is min correction allowed */
  52.  
  53. static BOOL set_clock        = FALSE;
  54.  
  55. static struct timer net_time_t;
  56. static struct socket time_socket;
  57.  
  58. static struct cmds time_cmds[] =
  59.     "maxcorrect",     do_maxcorrect, 0,    0,    NULLCHAR   , 
  60.     "mincorrect",    do_mincorrect, 0,    0,    NULLCHAR   , 
  61.     "read",            do_read,       0,    0,    NULLCHAR   , 
  62.     "server",        do_server,       0,    0,    NULLCHAR   , 
  63.     "set",            do_set,           0,    0,    NULLCHAR   , 
  64.     NULLCHAR   ,
  65. };
  66.  
  67. int dotime (int argc, char *argv[])
  68. {
  69.   return(subcmd(time_cmds, argc, argv));
  70. }
  71.  
  72. /* Display or set the timer server address. */
  73.  
  74. static int do_server(int argc, char *argv[])
  75. {
  76.   int32 n;                            /* temporary */
  77.  
  78.   if (argc < 2)
  79.   {
  80.     cwprintf(NULL, "%s\n", inet_ntoa(server));
  81.   }
  82.   else if (n = resolve(argv[1]), n == 0)
  83.   {
  84.     cwprintf(NULL, "Time - Bad host %s\n", argv[1]);
  85.     return (1);
  86.   }
  87.   else
  88.   {
  89.     server = n;
  90.   }
  91.   return (0);
  92. }
  93.  
  94. static void no_net_time(void *sk)
  95. {
  96.   cwprintf(NULL, "Time - No response from %s\n", inet_ntoa(server));
  97.   del_udp((struct socket *) sk);
  98.   set_clock = FALSE;
  99. }
  100.  
  101. time_t RiscTime(time_t *place)
  102. {
  103.   BOOL carry = FALSE;
  104.   char btime[] = "\x00\x00\x00\x00\x6A\x99\x6E\x33\x00";
  105.   char rtime[8], ntime[8], tzname[10];
  106.   int diff, loop, temp, tz;
  107.  
  108.   if (wimp_ver < 300)
  109.     return(time(place));
  110.     
  111.   os_swi2r(0x43048, NULL, NULL, (int *) tzname, &tz);
  112.   rtime[3] = 3;
  113.   os_word(14, &rtime[3]);
  114.   for (loop = 3; loop < 8; loop++)
  115.   {
  116.     temp = rtime[loop] - btime[loop] - carry;
  117.     ntime[loop] = temp & 0xFF;
  118.     carry = ((temp & 0x100) != 0);
  119.   }
  120.   diff = (*((int *) &ntime[4]));
  121.   temp = ((diff / 100) * 256) + (((diff % 100) * 256) + ntime[3]) / 100 + tz / 100;
  122.   if (place)
  123.     *place = temp;
  124.   return(temp);
  125. }
  126.  
  127. static void time_rec(struct socket *lsock, int16 rcvcnt)
  128. {
  129.   int loop;
  130.   struct socket fsocket;    /* socket address    */
  131.   struct mbuf *bp;
  132.   time_t pctime;            /* PC time            */
  133.   union
  134.   {
  135.     time_t time;
  136.     char bytes[sizeof (time_t)];
  137.   } result;                            /* data from remote    */
  138.  
  139.   if (recv_udp(lsock, &fsocket, &bp) != 4)
  140.   {
  141.     cwprintf(NULL, "TIME: receive failed\n");
  142.     stop_timer(&net_time_t);
  143.     del_udp(lsock);
  144.     done_set_time = FALSE;
  145.     return;
  146.   }
  147.   /* Calculate the correction value. */
  148.   loop = 0;
  149.   
  150.   while (pullone(&bp, &result.bytes[3 - loop]) == 1)
  151.     loop++;
  152.  
  153.   result.time -= 2208988800U;        /* adjust epoch    */
  154.  
  155.   pctime = RiscTime(NULL);
  156.   correction = result.time - pctime;
  157.   cwprintf(NULL, "TIME: correction = %ld seconds\n", correction);
  158.   cwprintf(NULL, "Net time   (GMT): %s", asctime (gmtime (&result.time)));
  159.   cwprintf(NULL, "Local time (GMT): %s", asctime (gmtime (&pctime)));
  160.   stop_timer(&net_time_t);
  161.   del_udp(lsock);
  162.  
  163.   if (set_clock)
  164.   {
  165.     char itime[8];
  166.     int correction_abs;
  167.  
  168.     correction_abs = (int) labs(correction);
  169.   
  170.     if (max_correction && correction_abs > max_correction)
  171.     {
  172.       cwprintf(NULL, "TIME: required correction (%ld) greater than maximum (%ld)\n",
  173.       correction, max_correction);
  174.       correction = 0;
  175.       return;
  176.     }
  177.   
  178.     if (min_correction && correction_abs < min_correction)
  179.     {
  180.       cwprintf(NULL, "TIME: required correction (%ld) less than minimum (%ld)\n",
  181.       correction, min_correction);
  182.       correction = 0;
  183.       return;
  184.     }
  185.     itime[0] = 3;
  186.     os_word(14, itime);
  187.     time_adj(itime, correction);
  188.     os_swi1(0x43047 /* Territory_SetTime */, (int) itime);
  189.     
  190.     correction = 0;                        /* no need for a correction now    */
  191.     cwprintf(NULL, "TIME: Arc clock reset\n");
  192.   }
  193.   set_clock = FALSE;
  194. }
  195.  
  196. /* Read the time from the remote and set the correction value. */
  197.  
  198. static int do_read(int argc, char *argv[])
  199. {
  200.   struct socket lsocket, fsocket;    /* socket address            */
  201.  
  202.   if (server == 0L)
  203.   {
  204.     cwprintf(NULL, "Time - Bad host %s\n", "0.0.0.0");
  205.     return (1);
  206.   }
  207.   if (run_timer(&net_time_t))
  208.   {
  209.     cwprintf(NULL, "Time - Already asking\n");
  210.     return (1);
  211.   }
  212.  
  213.   /* Set up the connection. */
  214.  
  215.   fsocket.address = server;
  216.   fsocket.port    = TIME_PORT;
  217.   lsocket.address = ip_addr;      /* our ip address */
  218.   lsocket.port    = lport++;      /* next unused port */
  219.  
  220.   open_udp(&lsocket, (void (*)())time_rec);
  221.   send_udp(&lsocket, &fsocket, 0, 0, 0, 0, 0, 0);
  222.   
  223.   time_socket     = lsocket;
  224.   net_time_t.func = no_net_time;  /* what to call on timeout */
  225.   net_time_t.arg  = (void *) &time_socket;
  226.   set_timer(&net_time_t, 30000);
  227.   start_timer(&net_time_t);
  228.   return(0);
  229. }
  230.  
  231.  
  232. /* Set the Arc's clock from the time server. */
  233.  
  234. static int do_set (int argc, char *argv[])
  235. {
  236.   if (do_read (0, NULL) != 0)
  237.     return (1);
  238.  
  239.   set_clock = TRUE;
  240.  
  241.   return (0);
  242. }
  243.  
  244.  
  245. static int do_maxcorrect(int argc, char *argv[])
  246. {
  247.   if(argc < 2)
  248.   {
  249.     cwprintf(NULL, "TIME: maximum correction: %d\n", max_correction);
  250.     return 0;
  251.   }
  252.   max_correction = atoi(argv[1]);
  253.   return 0;
  254. }
  255.  
  256. static int do_mincorrect(int argc, char *argv[])
  257. {
  258.   if(argc < 2)
  259.   {
  260.     cwprintf(NULL, "TIME: minimum correction: %d\n", min_correction);
  261.     return 0;
  262.   }
  263.   min_correction = atoi(argv[1]);
  264.   return 0;
  265. }
  266.